package repositories

import (
	"context"
	"fmt"
	"github.com/jmoiron/sqlx"
	"hysx/models"
	"strings"
)

// {{.StructName}}Repository {{.TableComment}}仓库
type {{.StructName}}Repository struct {
	DB *sqlx.DB
}

// Register{{.StructName}}Repository 创建并注册{{.TableComment}}仓库实例
func Register{{.StructName}}Repository(db *sqlx.DB) *{{.StructName}}Repository {
	return &{{.StructName}}Repository{DB: db}
}

// Insert{{.StructName}} 添加{{.TableComment}}
func (repository *{{.StructName}}Repository) Insert{{.StructName}}(ctx context.Context, {{.TabName}} *models.{{.StructName}}) {
	statement := generatorInsertSQL({{.TabName}}, "{{.TabName}}")
	_, err := repository.DB.NamedExecContext(ctx, statement, {{.TabName}})
	printlnSQL(statement, *{{.TabName}})
	if err != nil {
		if strings.Index(err.Error(), "Duplicate entry") != -1 {
			panic("{{.TableComment}}已存在！")
		}
		panic("{{.TableComment}}注册失败！" + err.Error())
	}
}

// Delete{{.StructName}} 删除{{.TableComment}}
func (repository *{{.StructName}}Repository) Delete{{.StructName}}(ctx context.Context, {{.TabName}}Id *int) {
	statement := "DELETE FROM {{.TabName}} WHERE id = ?"
	printlnSQL(statement, *{{.TabName}}Id)
	_, err := repository.DB.ExecContext(ctx, statement, *{{.TabName}}Id)
	if err != nil {
		panic("{{.TableComment}}删除失败！" + err.Error())
	}
}

// Update{{.StructName}} 更新{{.TableComment}}
func (repository *{{.StructName}}Repository) Update{{.StructName}}(ctx context.Context, {{.TabName}} *models.{{.StructName}}) {
	statement := generatorUpdateSQL({{.TabName}}, "{{.TabName}}")
	printlnSQL(statement, *{{.TabName}})
	_, err := repository.DB.NamedExecContext(ctx, statement, {{.TabName}})
	if err != nil {
		panic("{{.TableComment}}更新失败！" + err.Error())
	}
}

// Select{{.StructName}}List 查询{{.TableComment}}列表
func (repository *{{.StructName}}Repository) Select{{.StructName}}List(ctx context.Context, {{.TabName}} *models.{{.StructName}}, pageNum, pageSize int) PageInfo {
	statement, values := generatorQuery({{.TabName}}, "{{.TabName}}")
	printlnSQL(statement, values)
	var list []models.{{.StructName}}
	err := repository.DB.SelectContext(
		ctx,
		&list,
		fmt.Sprintf("%s LIMIT %d OFFSET %d", statement, pageSize, (pageNum-1)*pageSize),
		values...,
	)
	if err != nil {
		panic("查询{{.TableComment}}失败！" + err.Error())
	}
	countStatement := strings.Replace(statement, "*", "COUNT(1)", 1)
	var count int
	err = repository.DB.GetContext(ctx, &count, countStatement)
	if err != nil {
		panic("查询{{.TableComment}}失败!" + err.Error())
	}
	return getPageInfo(list, pageNum, pageSize, count)
}

// Select{{.StructName}}ByID 通过ID查询{{.TableComment}}
func (repository *{{.StructName}}Repository) Select{{.StructName}}ByID(ctx context.Context, {{.TabName}}Id *int) models.{{.StructName}} {
	statement := "SELECT * FROM {{.TabName}} WHERE id = ?"
	printlnSQL(statement, *{{.TabName}}Id)
	var {{.TabName}} models.{{.StructName}}
	err := repository.DB.GetContext(ctx, &{{.TabName}}, statement, *{{.TabName}}Id)
	if err != nil {
		panic("查询{{.TableComment}}失败！" + err.Error())
	}
	return {{.TabName}}
}

// Import{{.StructName}} 批量导入{{.TableComment}}
func (repository *{{.StructName}}Repository) Import{{.StructName}}(ctx context.Context, {{.TabName}}s []*models.{{.StructName}}) {
	statement := generatorInsertSQL({{.TabName}}s[0], "{{.TabName}}")
	printlnSQL(statement, {{.TabName}}s)
	_, err := repository.DB.NamedExecContext(ctx, statement, {{.TabName}}s)
	if err != nil {
		if strings.Contains(err.Error(), "Duplicate entry") {
			panic("批量插入失败，{{.TableComment}}已存在！" + err.Error())
		}
		panic("批量插入失败！" + err.Error())
	}
}

// Export{{.StructName}} 批量导出{{.TableComment}}
func (repository *{{.StructName}}Repository) Export{{.StructName}}(ctx context.Context, ids []string) []models.{{.StructName}} {
	statement, args, err := sqlx.In("SELECT * FROM {{.TabName}} WHERE id in (?)", ids)
	if err != nil {
		panic("批量导出失败！" + err.Error())
	}
	printlnSQL(statement, ids)
	var list []models.{{.StructName}}
	err = repository.DB.SelectContext(ctx, &list, statement, args...)
	if err != nil {
		panic("批量导出查询失败！" + err.Error())
	}
	return list
}
